#include <iostream>
#include <memory>
#include <string>

using std::cout;
using std::endl;
using std::shared_ptr;
using std::unique_ptr;
using std::string;

//和19的safefile做对比，
//都是 用打开的指针创建对象、写、写入、关闭。写入和关闭都放在fclose
//关键点在于关闭：safefile把fclose放在析构函数，而智能指针放在删除器里
//最后都不需要单独写fclose，否则会二次释放

struct FILECloser{
    void operator()(FILE *ptr) const
    {
        if(ptr){
            fclose(ptr);
            cout<<"fclose(ptr)"<<endl;
        }
    }
};

void test(){
    string msg("hello,world\n");
    unique_ptr<FILE,FILECloser> up(fopen("2.txt","a+"));
    fwrite(msg.c_str(),msg.size(),1,up.get());  //get为了获得裸指针
    //fclose(up.get());
    //如果不写这一句，写不进文件，msg停留在缓冲区，但是写了又会两次释放
    //因为unique_ptr的模板里有一个默认删除器，会把up所指空间释放
    //即fclose释放一次，删除器又释放一次
    
    //所以需要自己手写一个删除器，文件不能delete，那就fclose
    //额外说一点，原来删除器怎么写的就照着写，不要纠结传入的指针是否要变成裸指针
}

void test2(){
    string msg("hello,world\n");
    shared_ptr<FILE> sp(fopen("wuhan.txt","a+"),FILECloser());//传入的参数是删除器对象
    fwrite(msg.c_str(),msg.size(),1,sp.get());
    
    //fclose(sp.get());
    //同样会二次释放
}

int main()
{   
    test2();
    return 0;
}

